#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Project: spd-sxmcc
"""
@author: lyndon
@time Created on 2019/2/18 15:26
@desc Condition类：条件变量对象能让一个线程停下来，等待其它线程满足了某个“条件”。如，状态的改变或值的改变。

acquire 　　给线程上锁
wait        wait方法释放当前线程占用的锁，同时挂起线程，直至被唤醒或超时（需timeout参数）。
            当线程被唤醒并重新占有锁的时候，程序才会继续执行下去。
notify　　  唤醒一个挂起的线程（如果存在挂起的线程）。注：notify()方法不会释放所占用的锁。
notifyall   调用这个方法将通知等待池中所有线程，这些线程都将进入锁定池尝试获得锁定。
            此方法不会释放锁定。
            使用前线程必须已获得锁定，否则将抛出异常。
"""

import threading
import time

condition = threading.Condition()
products = 0


class Producer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        global condition, products
        while True:
            if condition.acquire():
                if products < 10:
                    products += 1
                    print("Producer(%s):deliver one, now products:%s" % (self.name, products))
                    condition.notify()
                else:
                    # print("Producer(%s):already 10, stop deliver, now products:%s" % (self.name, products))
                    condition.wait()
                condition.release()
                time.sleep(2)


class Consumer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        global condition, products
        while True:
            if condition.acquire():
                if products > 1:
                    products -= 1
                    print("Consumer(%s):consume one, now products:%s" % (self.name, products))
                    condition.notify()
                else:
                    # print("Consumer(%s):only 1, stop consume, products:%s" % (self.name, products))
                    condition.wait()
                condition.release()
                time.sleep(2)


if __name__ == "__main__":
    for p in range(0, 2):
        p = Producer()
        p.start()

    for c in range(0, 10):
        c = Consumer()
        c.start()
